package cn.wwcyc.config;

//作者：CodeGoat24
//        链接：https://www.zhihu.com/question/485970850/answer/2421348623
//        来源：知乎
//        著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。

import cn.wwcyc.controller.ServerEndPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;

import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //也可以用这里的跨域配置
    @Bean
    public CorsFilter corsFilter()
    {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        // 是否允许请求带有验证信息
        config.setAllowCredentials(true);

        // 允许访问的客户端域名
        // (springboot2.4以上的加入这一段可解决 allowedOrigins cannot contain the special value "*"问题)
        List<String> allowedOriginPatterns = new ArrayList<>();
        allowedOriginPatterns.add("*");
        config.setAllowedOriginPatterns(allowedOriginPatterns);

        // 设置访问源地址
        // config.addAllowedOrigin("*");
        // 设置访问源请求头
        config.addAllowedHeader("*");
        // 设置访问源请求方法
        config.addAllowedMethod("*");
        // 对接口配置跨域设置
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
    // 这个方法用来注册拦截器，我们自己写好的拦截器需要通过这里添加注册才能生效
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //添加自定义拦截器和拦截路径，此处对所有请求进行拦截，除了登录界面和登录接口
        //此处必须用appInterceptor()返回一个JWTInterceptor对象，
        //不能用new JWTInterceptor()
        // 因为new JWTInterceptor()不作为spring的bean管理，其中的userService spring无法注入
        //而appInterceptor()作为spring的bean管理。
        //这里无论appInterceptor() 调用多少次，生成的JWTInterceptor都是单例的，
        // 因为自身WebConfig类被代理了，（@Configuration注解的作用就是生成这个配置类的代理类）
        // 生出来一个代理类，代理类中appInterceptor()方法被增强，会先去ioc容器中查找Bean从而会保证单例！！
        //https://daimingzhi.blog.csdn.net/article/details/106008651?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-106008651-blog-106392167.235%5Ev43%5Epc_blog_bottom_relevance_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-106008651-blog-106392167.235%5Ev43%5Epc_blog_bottom_relevance_base3&utm_relevant_index=5

        Object oi = appInterceptor();
        Object oi2 = appInterceptor();

        registry.addInterceptor(appInterceptor()) //
                .addPathPatterns("/**")//添加拦截路径,拦截所有
//                .addPathPatterns("/api/sms/**")//添加拦截路径,拦截所有
                //注意 测试，放行了所有，正式上线时请打开  "/**" 表示放行所有
                .excludePathPatterns("/user/login", "/user/register", "/**/export", "/file/**", "/emp/**", "/city/**"); // 排除的拦截路径,

        WebMvcConfigurer.super.addInterceptors(registry);
    }

    @Bean
    public HandlerInterceptor appInterceptor(){
//        System.out.println("appInterceptor() called ");
        return new JWTInterceptor();
    }
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}